///////////////////////////////////////////////////////////////////////////
//
// Spring Engine Source File.
// Copyright (C), Dengtao 2011-2021
// ----------------------------------------------------------------------
// File name:   SfGameObjectManager.cpp
// Version:     v1.0.0
// Created:     2013/06/16 11:24 by dengtao
// Compilers:   Visual Studio 2008
// Description: 
// ----------------------------------------------------------------------
// History:
//
///////////////////////////////////////////////////////////////////////////

#include "SfGameObjectManager.h"
#include "SfGameObject.h"

namespace Sunflower
{
//
//Summary:
//	constructor.
GameObjectManager::GameObjectManager()
	: m_NextValidID(1)
{
}

//
//Summary:
//	destructor.
GameObjectManager::~GameObjectManager()
{
	UnregisterAll();
}

//
//Summary:
//	Register game object.
void GameObjectManager::Register(GameObject* gameObject)
{
	SfAssertValidPtr(gameObject);

	if (!gameObject->GetGoid().IsValidGoid())
	{
		gameObject->GetGoid().SetIntID(m_NextValidID);
		++m_NextValidID;
	}
	else
	{
		unsigned int int_id = gameObject->GetGoid().GetIntID();

		if (int_id > m_NextValidID)
		{
			m_NextValidID = int_id + 1;
		}
	}

	SfAssert(m_GoidBasedDict.find(gameObject->GetGoid()) == 
		m_GoidBasedDict.end());

	m_GoidBasedDict[gameObject->GetGoid()] = gameObject;
}

//
//Summary:
//	Unregisgter game object.
void GameObjectManager::Unregister(GameObject* gameObject)
{
	SfAssertValidPtr(gameObject);
	SfAssert(gameObject->GetGoid().IsValidGoid());
	SfAssert(m_GoidBasedDict.find(gameObject->GetGoid()) != 
		m_GoidBasedDict.end());

	m_GoidBasedDict.erase(gameObject->GetGoid());
}

//
//Summary:
//	unregister all game objects.
void GameObjectManager::UnregisterAll()
{
	m_GoidBasedDict.clear();
}

//
//Summary:
//	find game object by goic.
GameObject* GameObjectManager::GetGameObjectByGoid(
	const GameObjectGUID& goid)
{
	if (goid.IsValidGoid())
	{
		IDBasedGOMapIterator it = m_GoidBasedDict.find(goid);

		if (it != m_GoidBasedDict.end())
		{
			return it->second;
		}
	}

	return SfNull;
}

//
//Summary:
//	all game objects.
void GameObjectManager::IterateGameObjects(
	Delegate<void (GameObject*, void*)>& proc, void* args)
{
	for (IDBasedGOMapIterator it = m_GoidBasedDict.begin();
		 it != m_GoidBasedDict.end();
		 ++it)
	{
		SfAssertValidPtr(it->second);

		if (SfIsValidPtr(it->second))
		{
			proc((it->second), args);
		}
	}
}

}
